<?php

include "utilities.inc";
include "tokeniser.inc";
include "matcher.inc";
// abstract classes for the language data
include "lexicon.inc";
include "grammar.inc";
   
class parser {
  protected $lexer;
  protected $xmlMaker;
  protected $grammar;
  protected $tokenList;

  public function __construct( $language = 'english' ) {
    include "$language/grammar.inc";
    $this->xmlMaker = new blazonML('1.0');
    $grammarObjName = $language . 'Grammar';
    $this->grammar = new $grammarObjName($language, $this->xmlMaker);
  }
  
  public function parse($blazon, $format = 'xml' ) {
    // set things up
    $this->tokenList = new tokeniser($blazon);
    $topNode = $this->xmlMaker->makeNode(blazonML::E_BLAZON, array ( "blazonText" => $blazon));
    $this->xmlMaker->appendChild($topNode);

    // Do the parsing
    $node = $this->grammar->readGrammar($this->tokenList);
    if ( $node != null )
      $topNode->appendChild($node);
    
    // Return the result
    switch ( $format ) {
      case 'dom':
        return $this->xmlMaker;
        break;
      case 'xml':
      default:
        return $this->xmlMaker->saveXML();
        break;
      }
    }
    
    public function getErrors( $format = 'text' ) {
    if ( !($messages = $this->grammar->getMessages()) ) return null;
    
    switch ( $format ) {
    case 'array':
       return $messages;
       break;
      case 'html':
        $prefix = $postfix = '';
        $linePre = '<p><em>';
        $sep = '</em>&nbsp;&lt;-&nbsp;';
        $linePost = "</p>\n";
        break;
      case 'text':
      default:
        $prefix = $postfix = $linePre = '';
        $linePost = "\n";
        $sep = ' <- ';
        break;
     }
     
     $output = $prefix;
     foreach ( $messages as $message ) {
       $output .= $linePre;
       if (isset($message[2])) $output .= $message[2];
       $output .= $sep;
       $output .= "$message[1] ($message[0])";
       $output .= $linePost;
     }
     $output .= $postfix;
     return $output;
  }

}

?>
